<template>
  <!-- 模板内容保持不变 -->
  <div class="task-management">    
    <!-- 上部分：筛选条件 -->
    <div class="filter-bar">
      <div class="filter-controls">
        <el-input
            v-model="filterTaskName"
            placeholder="任务名称"
            clearable
            style="width: 200px"
        >
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
        <el-date-picker
            v-model="filterStartTime"
            type="datetime"
            placeholder="开始时间"
            format="YYYY-MM-DD HH:mm:ss"
            value-format="YYYY-MM-DD HH:mm:ss:SSS"
            style="width: 180px"
            clearable
            :disabled-date="disabledStartDate"
            @change="onFilterStartTimeChange"
        />
        <el-date-picker
            v-model="filterEndTime"
            type="datetime"
            placeholder="结束时间"
            format="YYYY-MM-DD HH:mm:ss"
            value-format="YYYY-MM-DD HH:mm:ss:SSS"
            style="width: 180px"
            clearable
            :disabled-date="disabledEndDate"
            @change="onFilterEndTimeChange"
        />
        <el-select
            v-model="filterStatus"
            placeholder="任务状态"
            clearable
            style="width: 120px"
        >
          <el-option label="全部状态" value="" />
          <el-option label="正常" value="0" />
          <el-option label="停用" value="1" />
        </el-select>
        <el-button type="primary" @click="searchTasks">
          查询
        </el-button>
        <el-button @click="resetFilter">
          重置
        </el-button>
      </div>
    </div>

    <!-- 下部分：任务表格（包含批量选择和批量导出功能） -->
    <div class="table-section">
      <div class="table-header">
        <h3>任务列表</h3>
        <!-- 已选任务大小提示 -->
        <div class="selected-size-hint" v-if="selectedTaskIds.length > 0">
          已选{{ selectedTaskIds.length }}个任务，总大小：{{ formatSelectedSize() }}
        </div>
        <div class="table-controls">
          <!-- 批量导出按钮 -->
          <el-button
              size="small"
              type="primary"
              @click="batchExportTasks"
              :disabled="selectedTaskIds.length === 0"
              :loading="batchExportLoading"
          >
            批量导出
          </el-button>
          <el-button size="small" type="primary" @click="openFile">
            导入
          </el-button>
          <el-button size="small" type="success" @click="addNewTask">
            添加任务
          </el-button>
        </div>
      </div>
      <div class="table-container">
        <el-table
            :data="paginatedTaskData"
            style="width: 100%; height: 100%;"
            stripe
            :header-cell-style="{ background: '#f8f9fa', color: '#333', fontWeight: '500', textAlign: 'center' }"
            :cell-style="{ textAlign: 'center' }"
            border
            v-loading="loading"
            @selection-change="handleSelectionChange"
            ref="taskTableRef"
        >
          <!-- 多选框列 -->
          <el-table-column
              type="selection"
              width="55"
              align="center"
              :selectable="canSelectTask"
          />
          <el-table-column prop="taskId" label="序号" width="80" align="center" />
          <el-table-column prop="taskName" label="任务名称" min-width="200" align="center" />
          <el-table-column prop="taskTypeName" label="任务类型" min-width="70" align="center" />
          <el-table-column prop="startTime" label="任务开始时间" min-width="160" align="center">
            <template #default="scope">
              <div class="time-cell">
                <el-icon><Clock /></el-icon>
                <span>{{ formatTaskTime(scope.row.startTime) }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="endTime" label="任务结束时间" min-width="160" align="center">
            <template #default="scope">
              <div class="time-cell">
                <el-icon><Clock /></el-icon>
                <span>{{ formatTaskTime(scope.row.endTime) }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="status" label="状态" width="100" align="center">
            <template #default="scope">
              <el-tag :type="getTaskStatusType(scope.row.status)" size="small">
                {{ getTaskStatusText(scope.row.status) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column
              prop="isArchived"
              label="归档状态"
              width="100"
              align="center"
          >
            <template #default="scope">
              <el-tag
                  :type="scope.row.isArchived === 1 ? 'success' : 'warning'"
                  size="small"
              >
                {{ scope.row.isArchived === 1 ? "已归档" : "未归档" }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="totalFileSize" label="文件大小" min-width="110" align="center">
            <template #default="scope">
              <div class="time-cell">
                <span>{{ scope.row.totalFileSize }}M</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="280" align="center" fixed="right">
            <template #default="scope">
              <div class="action-buttons">
                <el-button
                    size="small"
                    type="primary"
                    @click="exportTask(scope.row)"
                    v-if="scope.row.isArchived === 1"
                >
                  导出
                </el-button>
                <el-button size="small" type="primary" v-if="scope.row.isArchived === 1" @click="goToDataDetail(scope.row)">
                  查看数据
                </el-button>
                <el-button size="small" type="warning" @click="editTask(scope.row)">
                  编辑
                </el-button>
                <el-button size="small" type="danger" @click="deleteTask(scope.row)">
                  删除
                </el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="pagination-container">
        <div class="pagination-info">
          <span>共 {{ total }} 条记录，当前显示第 {{ (currentPage - 1) * pageSize + 1 }} - {{ Math.min(currentPage * pageSize, total) }} 条</span>
        </div>
        <el-pagination
            :current-page="currentPage"
            :page-size="pageSize"
            :page-sizes="[10, 20, 50, 100]"
            layout="sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            small
        />
      </div>
    </div>

    <!-- 添加/编辑任务弹窗 -->
    <el-dialog
        v-model="showAddDialog"
        :title="isEdit ? '编辑任务' : '添加任务'"
        width="600px"
        :close-on-click-modal="false"
    >
      <el-form :model="taskForm" label-width="120px" :rules="taskRules" ref="taskFormRef">
        <el-form-item label="任务名称" prop="taskName">
          <el-input
              v-model="taskForm.taskName"
              placeholder="请输入任务名称"
              maxlength="50"
              show-word-limit
          />
        </el-form-item>
        <el-form-item label="开始时间" prop="startTime">
          <el-date-picker
              v-model="taskForm.startTime"
              type="datetime"
              placeholder="选择开始时间"
              style="width: 100%"
              format="YYYY-MM-DD HH:mm:ss"
              value-format="YYYY-MM-DD HH:mm:ss:SSS"
              :disabled-date="disabledFormStartDate"
              @change="onFormStartTimeChange"
          />
        </el-form-item>
        <el-form-item label="结束时间" prop="endTime">
          <el-date-picker
              v-model="taskForm.endTime"
              type="datetime"
              placeholder="选择结束时间"
              style="width: 100%"
              format="YYYY-MM-DD HH:mm:ss"
              value-format="YYYY-MM-DD HH:mm:ss:SSS"
              :disabled-date="disabledFormEndDate"
              @change="onFormEndTimeChange"
          />
        </el-form-item>
        <el-form-item label="任务类型" prop="taskType">
          <el-select v-model="taskForm.taskType" placeholder="请选择任务类型" style="width: 100%">
            <el-option 
              v-for="option in taskTypeOptions" 
              :key="option.id" 
              :label="option.typeName" 
              :value="option.id" 
            />
          </el-select>
        </el-form-item>
        <el-form-item label="任务状态" prop="status">
          <el-select v-model="taskForm.status" placeholder="请选择任务状态" style="width: 100%">
            <el-option label="正常" value="0" />
            <el-option label="停用" value="1" />
          </el-select>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
              v-model="taskForm.remark"
              type="textarea"
              :rows="3"
              placeholder="请输入任务备注信息"
              maxlength="200"
              show-word-limit
          />
        </el-form-item>
        <el-form-item label="关联采集数据" prop="dataIds" v-if="!isEdit">
          <el-select
              v-model="taskForm.dataIds"
              multiple
              filterable
              placeholder="请选择要关联的采集数据"
              style="width: 100%"
              v-loading="collectionDataLoading"
          >
            <el-option
                v-for="item in collectionDataOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="关联数据" v-else>
          <div class="associated-data-container">
            <div class="data-summary">
              <el-icon><DataLine /></el-icon>
              <span>已关联 {{ taskForm.dataIds.length }} 个采集数据</span>
            </div>
            <div v-if="taskForm.dataIds.length > 0" class="data-list">
              <div
                  v-for="dataId in taskForm.dataIds"
                  :key="dataId"
                  class="data-item"
              >
                <el-icon class="item-icon"><VideoPlay /></el-icon>
                <span class="item-text">
                  数据{{ dataId }} - {{ getTimestampFromVideoDataList(dataId) }}
                </span>
              </div>
            </div>
            <div v-else class="no-associated-data">
              <el-empty description="暂无关联数据" :image-size="60" />
            </div>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="cancelEdit">取消</el-button>
        <el-button
            type="primary"
            @click="saveTask"
            :loading="saveLoading"
        >
          {{ isEdit ? '更新' : '保存' }}
        </el-button>
      </template>
    </el-dialog>

    <!-- 查看任务数据弹窗 -->
    <el-dialog
        v-model="showDataDialog"
        title="任务关联数据"
        width="90%"
        top="5vh"
        :close-on-click-modal="false"
    >
      <div class="task-data-content">
        <el-tabs v-model="activeTab">
          <el-tab-pane label="采集数据列表" name="list">
            <el-table :data="relatedCollectionData" style="width: 100%">
              <el-table-column prop="id" label="序号" width="80" align="center" />
              <el-table-column prop="startTime" label="采集开始时间" width="180" align="center" />
              <el-table-column prop="endTime" label="采集结束时间" width="180" align="center" />
              <el-table-column prop="duration" label="时长" width="120" align="center" />
              <el-table-column label="操作" align="center">
                <template #default="scope">
                  <el-button size="small" type="primary" @click="viewCollectionDetail(scope.row)">
                    查看详情
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-tab-pane>
          <el-tab-pane label="数据统计" name="stats">
            <div class="stats-content">
              <div class="stat-item">
                <h4>总采集次数</h4>
                <p class="stat-number">{{ relatedCollectionData.length }}</p>
              </div>
              <div class="stat-item">
                <h4>总采集时长</h4>
                <p class="stat-number">{{ calculateTotalDuration() }}</p>
              </div>
              <div class="stat-item">
                <h4>数据完整性</h4>
                <p class="stat-number">98.5%</p>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-dialog>

    <!-- 导入弹窗 -->
    <el-dialog
        v-model="showFileDialog"
        title="导入"
        width="50%"
        top="5vh"
        :close-on-click-modal="false"
    >
      <div class="upload-container">
        <el-button
            size="small"
            type="primary"
            @click="openFileDialog"
            :loading="importLoading"
        >
          <Folder /> 选择导入压缩包
        </el-button>
        <div v-if="selectedFile" class="file-info" style="margin: 16px 0; padding: 12px; border: 1px solid #e4e7ed; border-radius: 8px; background: #f8f9fa;">
          <h3 style="margin: 0 0 8px 0; font-size: 14px; color: #333; font-weight: 500;">已选择文件</h3>
          <div style="display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: #666;">
            <p><span style="color: #333;">文件名：</span>{{ selectedFile.name }}</p>
            <p><span style="color: #333;">文件路径：</span>{{ selectedFile.path }}</p>
            <p><span style="color: #333;">文件大小：</span>{{ formatFileSize(selectedFile.size) }}</p>
          </div>
        </div>
        <div class="button-group" style="margin-top: 16px; display: flex; gap: 10px;">
          <el-button
              type="success"
              :disabled="!selectedFile"
              @click="uploadFile"
              :loading="importLoading"
          >
            开始导入
          </el-button>
          <el-button
              type="info"
              @click="clearSelection"
              :loading="importLoading"
          >
            清除选择
          </el-button>
        </div>
      </div>
    </el-dialog>

    <!-- 导出进度条 + 全局Loading遮罩 -->
    <div class="export-loading-mask" v-if="isExporting">
      <div class="loading-content">
        <el-icon class="loading-spinner">
          <Loading />
        </el-icon>
        <div class="progress-text">{{ progressText }}</div>
        <el-progress
            :percentage="exportProgress"
            :status="exportProgress === 100 ? 'success' : 'active'"
            stroke-width="8"
            style="width: 300px; margin-top: 20px;"
        />
      </div>
    </div>

    <!-- 导入进度条遮罩 -->
    <div class="export-loading-mask" v-if="isImporting">
      <div class="loading-content">
        <el-icon class="loading-spinner">
          <Loading />
        </el-icon>
        <div class="progress-text">{{ importProgressText }}</div>
        <el-progress
            :percentage="importProgress"
            :status="importProgress === 100 ? 'success' : 'active'"
            stroke-width="8"
            style="width: 400px; margin-top: 20px;"
        />
      </div>
    </div>

    <!-- 数据选择对话框 -->
    <el-dialog
      v-model="showDataSelectDialog"
      title="选择查看数据"
      width="800px"
      center
    >
      <div class="data-cards-container">
        <el-card
          v-for="data in selectedDataList"
          :key="data.dataId"
          class="data-card"
        >
          <div class="card-content">
            <div class="data-info">
              <div class="data-info-row">
                <div class="info-item">
                  <span class="info-label">数据ID:</span>
                  <span class="info-value">{{ data.dataId }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">遥测数据任务ID:</span>
                  <span class="info-value">{{ data.collectionTaskId }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">遥测数据任务名称:</span>
                  <span class="info-value">{{ data.collectionTaskName }}</span>
                </div>
              </div>
            </div>
            <div class="action-buttons">
              <el-button type="primary" @click="selectAndGoToDetail(data)">
                查看
              </el-button>
            </div>
          </div>
        </el-card>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, nextTick } from 'vue'
import { ElMessage, ElMessageBox, ElEmpty, ElProgress } from 'element-plus'
import { useRouter } from 'vue-router'
import {
  Clock, Search, DataLine, VideoPlay,
  Folder, Loading
} from '@element-plus/icons-vue'
import dayjs from 'dayjs'
import { taskAPI, dataAPI, API_CONFIG, taskTypeAPI } from '../api/index.js'
import request from "../api/request";

const router = useRouter()

// -------------------------- 基础响应式数据 --------------------------
const filterTaskName = ref('')
const filterStartTime = ref('')
const filterEndTime = ref('')
const filterStatus = ref('')
const currentPage = ref(1)
const pageSize = ref(20)
const total = ref(0)
const showAddDialog = ref(false)
const showDataDialog = ref(false)
const isEdit = ref(false)
const activeTab = ref('list')
const taskFormRef = ref()
const treeRef = ref()
const loading = ref(false)
const saveLoading = ref(false)
const exportloading = ref(false)
const collectionDataLoading = ref(false)
const showFileDialog = ref(false)
const exportTaskUrl = ref('')
const videoPath = ref(API_CONFIG.IMAGE_URL);
const taskList = ref([])
const downloadMsg = ref('');
const downloadSuccess = ref(false);
const collectionDataOptions = ref([])
const currentTaskVideoDataList = ref([])
const taskTypeOptions = ref([])
const cachedData = ref(null);
const cachedFilters = ref(null);
const relatedCollectionData = ref([])

// -------------------------- 批量导出相关状态 --------------------------
const taskTableRef = ref(null); // 表格引用
const selectedTaskIds = ref([]); // 选中的任务ID列表
const selectedTasks = ref([]); // 选中的任务完整数据
const batchExportLoading = ref(false); // 批量导出加载状态
const MAX_EXPORT_SIZE = 5 * 1024 * 1024 * 1024; // 5GB（字节）
const MAX_SIZE_MB = 5 * 1024; // 5GB = 5120MB

// 导出进度相关状态
const exportProgress = ref(0); // 导出进度（0-100）
const isExporting = ref(false); // 是否正在导出（控制Loading遮罩）
const progressText = ref("准备导出..."); // 进度提示文本

// 导入进度相关状态
const isImporting = ref(false); // 是否正在导入（控制遮罩显示）
const importProgress = ref(0); // 导入进度（0-100）
const importProgressText = ref("准备导入..."); // 进度提示文本

// 任务表单数据
const taskForm = ref({
  taskId: '',
  taskName: '',
  startTime: '',
  endTime: '',
  status: '0', // 默认状态：0=正常
  remark: '',
  dataIds: [], // 关联的采集数据ID列表
  taskType: null,
})

// 表单验证规则
const taskRules = {
  taskName: [
    { required: true, message: '请输入任务名称', trigger: 'blur' },
    { min: 2, max: 50, message: '任务名称长度在 2 到 50 个字符', trigger: 'blur' }
  ],
  startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
  endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
  status: [{ required: true, message: '请选择任务状态', trigger: 'change' }],
  remark: [{ required: true, message: '请输入备注信息', trigger: 'blur' }],
  dataIds: [{ required: false, message: '请选择关联的采集数据', trigger: 'change' }],
  taskType: [{ required: true, message: '请选择任务类型', trigger: 'change' }]
}

// -------------------------- 加载数据方法 --------------------------
const loadTaskTypeOptions = async () => {
  try {
    // 修正：添加基础路径并确保URL正确
    const result = await taskTypeAPI.getTaskPullDownList();
    if (result && result.code === 0) {
      console.log('任务类型列表:', result.data || []);

      taskTypeOptions.value = result.data || [];
    } else {
      throw new Error(result?.msg || '获取任务类型失败');
    }
  } catch (error) {
    console.error('加载任务类型失败:', error);
    ElMessage.error(`加载任务类型失败: ${error.message}`);
    taskTypeOptions.value = [];
  }
};

// 加载任务列表
const loadTaskList = async () => {
  loading.value = true;
  try {
    const params = {
      pageNum: currentPage.value,
      pageSize: pageSize.value,
      taskName: filterTaskName.value || '',
      startTime: filterStartTime.value || '',
      endTime: filterEndTime.value || '',
      status: filterStatus.value || ''
    };

    console.log('请求任务列表参数:', params);

    // 关键修复：确保API路径正确，添加基础URL前缀
    const result = await taskAPI.getTaskList(params);

    if (result && result.code === 0) {
      taskList.value = result.rows || [];
      total.value = result.total || 0;
      console.log('任务列表加载成功:', taskList.value.length, '个任务，总计:', total.value);
    } else {
      throw new Error(result?.msg || '获取任务列表失败');
    }
  } catch (error) {
    console.error('加载任务列表失败:', error);
    ElMessage.error(`加载任务列表失败: ${error.message}`);
    taskList.value = [];
    total.value = 0;
  } finally {
    loading.value = false;
  }
};

// 加载采集数据选项
const loadCollectionDataOptions = async () => {
  collectionDataLoading.value = true;
  try {
    // 使用正确的关联采集数据接口
    const result = await dataAPI.getDataDropdown();

    if (result && result.code === 0) {
      // 转换数据格式，使用storagePath中的时间戳
      collectionDataOptions.value = (result.data || []).map(item => {
        const timestamp = getTimestampFromStoragePath(item.storagePath);
        return {
          value: item.dataId,
          label: `数据${item.dataId} - ${timestamp} (${item.collectDuration})`,
          startTime: item.startCollectTime ? item.startCollectTime.split(':').slice(0, 3).join(':') : '',
          duration: item.collectDuration || '',
          storagePath: item.storagePath || '',
          timestamp: timestamp,
          fileSize: item.fileSize || 0 // 存储文件大小（字节）
        };
      });
      console.log('采集数据选项加载成功:', collectionDataOptions.value.length, '个选项');
    } else {
      throw new Error(result?.msg || '获取采集数据选项失败');
    }
  } catch (error) {
    console.error('加载采集数据选项失败:', error);
    ElMessage.error(`加载采集数据选项失败: ${error.message}`);
    collectionDataOptions.value = [];
  } finally {
    collectionDataLoading.value = false;
  }
};

// 分页数据
const paginatedTaskData = computed(() => {
  return taskList.value;
});

// -------------------------- 工具函数 --------------------------
const formatTaskTime = (timeStr) => {
  if (!timeStr) return '-';
  // 处理带毫秒的时间格式 "2025-07-30 12:12:32:138"
  return timeStr.split(':').slice(0, 3).join(':');
};

const getTaskStatusType = (status) => {
  const statusMap = {
    '0': 'success',   // 正常
    '1': 'danger'     // 停用
  };
  return statusMap[status] || 'info';
};

const getTaskStatusText = (status) => {
  const statusMap = {
    '0': '正常',
    '1': '停用'
  };
  return statusMap[status] || '未知';
};

// 从storagePath中提取时间戳
const getTimestampFromStoragePath = (storagePath) => {
  if (!storagePath) return '未知时间';

  // 从storagePath中提取时间戳
  const match = storagePath.match(/(\d{8}_\d{6})$/);
  if (match) {
    return match[1]; // 直接返回原始时间戳，如：20250731_172956
  }
  return '未知时间';
};

// 根据dataId获取时间戳显示
const getTimestampFromDataId = (dataId) => {
  const option = collectionDataOptions.value.find(item => item.value === dataId);
  if (option && option.timestamp) {
    return option.timestamp;
  }
  return '未知时间';
};

// 从videoDataList中根据dataId获取时间戳
const getTimestampFromVideoDataList = (dataId) => {
  const videoData = currentTaskVideoDataList.value.find(item => item.dataId === dataId);
  if (videoData && videoData.storagePath) {
    return getTimestampFromStoragePath(videoData.storagePath);
  }
  // 如果videoDataList中没有找到，则从collectionDataOptions中查找
  return getTimestampFromDataId(dataId);
};

// 根据videoDataList获取关联数据信息
const getAssociatedDataFromVideoDataList = (videoDataList) => {
  if (!videoDataList || !Array.isArray(videoDataList)) return [];

  return videoDataList.map(item => ({
    dataId: item.dataId,
    timestamp: getTimestampFromStoragePath(item.storagePath),
    duration: item.collectDuration,
    storagePath: item.storagePath
  }));
};

const calculateTotalDuration = () => {
  // 简单计算总时长
  const totalMinutes = relatedCollectionData.value.reduce((total, item) => {
    const duration = item.duration
    if (duration.includes('分钟')) {
      return total + parseInt(duration)
    } else if (duration.includes('小时')) {
      return total + parseInt(duration) * 60
    }
    return total
  }, 0)

  const hours = Math.floor(totalMinutes / 60)
  const minutes = totalMinutes % 60
  return hours > 0 ? `${hours}小时${minutes}分钟` : `${minutes}分钟`
}

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (!bytes || bytes === 0) return '0 B';
  const units = ['B', 'KB', 'MB', 'GB'];
  const exponent = Math.floor(Math.log(bytes) / Math.log(1024));
  return (bytes / Math.pow(1024, exponent)).toFixed(2) + ' ' + units[exponent];
};

// -------------------------- 批量导出相关函数 --------------------------
/**
 * 检查任务是否已归档
 */
const checkTaskArchived = (task) => {
  return task.isArchived === 1;
};

/**
 * 计算选中任务总文件大小（适配totalFileSize字段，单位：MB → 字节）
 */
const calculateTotalFileSize = (tasks) => {
  return tasks.reduce((total, task) => {
    // 关键：表格中totalFileSize单位为MB，需转换为字节（1MB = 1024*1024 字节）
    const taskSizeMB = task.totalFileSize ? Number(task.totalFileSize) : 0;
    const taskSizeBytes = taskSizeMB * 1024 * 1024;
    return total + taskSizeBytes;
  }, 0);
};

/**
 * 格式化已选任务大小（用于用户提示）
 */
const formatSelectedSize = () => {
  const totalSizeBytes = calculateTotalFileSize(selectedTasks.value);
  const totalSizeMB = totalSizeBytes / (1024 * 1024);
  const totalSizeGB = totalSizeMB / 1024;
  return totalSizeGB >= 1
      ? `${totalSizeGB.toFixed(2)}GB（${totalSizeMB.toFixed(1)}MB）`
      : `${totalSizeMB.toFixed(1)}MB`;
};

/**
 * 批量导出前的前置校验（归档+大小）
 */
const preCheckForBatchExport = (tasks) => {
  // 校验1：无选中任务
  if (tasks.length === 0) {
    return { pass: false, message: '请先选择要导出的任务' };
  }

  // 校验2：存在未归档任务
  const unarchivedTasks = tasks.filter(task => !checkTaskArchived(task));
  if (unarchivedTasks.length > 0) {
    const unarchivedNames = unarchivedTasks.map(t => t.taskName).join('、');
    return {
      pass: false,
      message: `以下任务未归档，请先归档后再导出：\n${unarchivedNames}`
    };
  }

  // 校验3：文件总大小超过5GB
  const totalSizeMB = calculateTotalFileSize(tasks) / (1024 * 1024); // 转MB用于用户提示
  if (totalSizeMB > MAX_SIZE_MB) {
    return {
      pass: false,
      message: `选中任务总文件大小为${totalSizeMB.toFixed(1)}MB，超过5GB（5120MB）限制，请减少选择数量`
    };
  }

  // 所有校验通过
  const totalSizeGB = totalSizeMB / 1024;
  return {
    pass: true,
    message: `选中${tasks.length}个已归档任务，总大小${totalSizeMB.toFixed(1)}MB（约${totalSizeGB.toFixed(2)}GB），可开始导出`
  };
};

/**
 * 表格多选事件：更新选中的任务ID和完整数据
 */
const handleSelectionChange = (selectedRows) => {
  selectedTasks.value = selectedRows;
  selectedTaskIds.value = selectedRows.map(task => task.taskId);
  console.log('当前选中任务：', selectedTaskIds.value);
};

/**
 * 控制任务是否允许被选择（新增：选择时实时校验总大小，超5G则禁用选择）
 */
const canSelectTask = (task) => {
  // 基础条件：仅“正常”状态（status: '0'）的任务可选择
  if (task.status !== '0') return false;

  // 新增：模拟“当前选中+待选任务”的总大小，判断是否超5G
  const currentTotalSizeBytes = calculateTotalFileSize(selectedTasks.value);
  const taskSizeMB = task.totalFileSize ? Number(task.totalFileSize) : 0;
  const taskSizeBytes = taskSizeMB * 1024 * 1024;
  const newTotalSizeBytes = currentTotalSizeBytes + taskSizeBytes;

  // 若选择当前任务后总大小超5G，则禁用选择
  if (newTotalSizeBytes > MAX_EXPORT_SIZE) {
    return false;
  }

  return true;
};

/**
 * 批量导出核心逻辑
 */
const batchExportTasks = async () => {
  // 前置校验
  const checkResult = preCheckForBatchExport(selectedTasks.value);
  if (!checkResult.pass) {
    // 校验失败：弹窗提示
    await ElMessageBox.alert(checkResult.message, '导出校验失败', {
      type: 'warning',
      confirmButtonText: '确定'
    });
    return;
  }

  // 校验通过：提示用户确认导出
  await ElMessageBox.confirm(
      `${checkResult.message}\n\n导出过程可能需要一段时间，请耐心等待`,
      '确认批量导出',
      {
        confirmButtonText: '开始导出',
        cancelButtonText: '取消',
        type: 'info'
      }
  );

  // 初始化导出状态
  isExporting.value = true; // 显示全局Loading
  exportProgress.value = 0;
  progressText.value = "正在生成压缩包...";
  batchExportLoading.value = true;

  try {
    // 构建批量导出参数（任务ID列表）
    const exportParams = {
      taskIds: selectedTaskIds.value.join(',') // 格式："1,2,3"
    };

    // 1. 调用批量导出接口，获取压缩包地址
    // 关键修复：检查并修正导出接口路径
    const exportResult = await taskAPI.exportVideoDataTask(exportParams);
    if (exportResult.code !== 0) {
      throw new Error(exportResult.msg || '批量导出接口调用失败');
    }

    const fileUrl = exportResult.data;
    if (!fileUrl) {
      throw new Error('接口未返回批量导出压缩包地址');
    }

    // 2. 调用Electron保存文件
    // 关键修复：确保文件URL拼接正确
    const fullFileUrl = `${API_CONFIG.BASE_URL}${fileUrl}`;
    const defaultFileName = `批量导出任务_${dayjs().format('YYYYMMDDHHmmss')}.zip`;

    // 请求保存路径
    const savePathResult = await window.electronAPI.requestSavePath(defaultFileName);
    if (savePathResult.canceled) {
      ElMessage.info('已取消批量导出');
      return;
    }
    if (savePathResult.error) {
      throw new Error(savePathResult.error);
    }

    // 3. 下载文件（带进度监听）
    progressText.value = "正在下载压缩包...";
    const downloadResult = await window.electronAPI.downloadFileWithProgress(
        {
          fileUrl: fullFileUrl,
          savePath: savePathResult.filePath
        },
        // 进度回调作为第二个参数
        (progress) => {
          exportProgress.value = Math.floor(progress.percent * 100);
          progressText.value = `正在下载：${exportProgress.value}%（${progress.transferred} / ${progress.total}）`;
        }
    ).catch(error => {
      ElMessage.error(`下载失败: ${error.message}`);
      console.error('下载错误:', error);
      return { success: false, message: error.message };
    });

    // 导出成功
    if (downloadResult.success) {
      exportProgress.value = 100;
      progressText.value = "导出完成！";
      downloadSuccess.value = true;
      downloadMsg.value = `批量导出完成！文件保存至：\n${savePathResult.filePath}`;
      ElMessage.success(downloadMsg.value);
      // 清空选中状态
      taskTableRef.value?.clearSelection();
      selectedTaskIds.value = [];
      selectedTasks.value = [];
    } else {
      throw new Error(downloadResult.message || '批量导出文件下载失败');
    }

  } catch (error) {
    // 导出失败处理
    exportProgress.value = 0;
    progressText.value = "导出失败";
    downloadSuccess.value = false;
    downloadMsg.value = `批量导出失败：${error.message}`;
    ElMessage.error(downloadMsg.value);
    console.error('批量导出异常：', error);
  } finally {
    // 结束导出（关闭Loading，延迟重置进度）
    batchExportLoading.value = false;
    // 成功时保留1秒进度条，提升用户体验
    setTimeout(() => {
      isExporting.value = false;
      exportProgress.value = 0;
    }, downloadSuccess.value ? 1000 : 0);
  }
};

// -------------------------- 时间验证函数 --------------------------
// 筛选区域
const disabledStartDate = (time) => {
  // 开始时间不能选择未来的日期
  const today = new Date()
  today.setHours(23, 59, 59, 999)

  // 如果已选择结束时间，开始时间不能大于结束时间
  if (filterEndTime.value) {
    const endDate = new Date(filterEndTime.value)
    return time.getTime() > Math.min(today.getTime(), endDate.getTime())
  }

  return time.getTime() > today.getTime()
}

const disabledEndDate = (time) => {
  // 结束时间不能选择未来的日期
  const today = new Date()
  today.setHours(23, 59, 59, 999)

  // 如果已选择开始时间，结束时间不能小于开始时间
  if (filterStartTime.value) {
    const startDate = new Date(filterStartTime.value)
    return time.getTime() < startDate.getTime() || time.getTime() > today.getTime()
  }

  return time.getTime() > today.getTime()
}

const onFilterStartTimeChange = (value) => {
  if (value && filterEndTime.value) {
    const startDate = new Date(value)
    const endDate = new Date(filterEndTime.value)

    if (startDate.getTime() > endDate.getTime()) {
      filterEndTime.value = ''
      ElMessage.warning('开始时间不能大于结束时间，已重置结束时间')
    }
  }
  console.log('筛选开始时间变化:', value)
}

const onFilterEndTimeChange = (value) => {
  if (value && filterStartTime.value) {
    const startDate = new Date(filterStartTime.value)
    const endDate = new Date(value)

    if (endDate.getTime() < startDate.getTime()) {
      filterEndTime.value = ''
      ElMessage.warning('结束时间不能小于开始时间，请重新选择')
      return
    }
  }
  console.log('筛选结束时间变化:', value)
}

// 表单区域
const disabledFormStartDate = (time) => {
  // 如果已选择结束时间，开始时间不能大于结束时间
  if (taskForm.value.endTime) {
    const endDate = new Date(taskForm.value.endTime)
    return time.getTime() > endDate.getTime()
  }
  return false
}

const disabledFormEndDate = (time) => {
  // 如果已选择开始时间，结束时间不能小于开始时间
  if (taskForm.value.startTime) {
    const startDate = new Date(taskForm.value.startTime)
    return time.getTime() < startDate.getTime()
  }
  return false
}

const onFormStartTimeChange = (value) => {
  if (value && taskForm.value.endTime) {
    const startDate = new Date(value)
    const endDate = new Date(taskForm.value.endTime)

    if (startDate.getTime() > endDate.getTime()) {
      taskForm.value.endTime = ''
      ElMessage.warning('开始时间不能大于结束时间，已重置结束时间')
    }
  }
  console.log('表单开始时间变化:', value)
}

const onFormEndTimeChange = (value) => {
  if (value && taskForm.value.startTime) {
    const startDate = new Date(taskForm.value.startTime)
    const endDate = new Date(value)

    if (endDate.getTime() < startDate.getTime()) {
      taskForm.value.endTime = ''
      ElMessage.warning('结束时间不能小于开始时间，请重新选择')
      return
    }
  }
  console.log('表单结束时间变化:', value)
}

// -------------------------- 业务操作函数 --------------------------
// 数据选择对话框相关
const showDataSelectDialog = ref(false);
const selectedDataList = ref([]);

// 跳转到数据详情页
const goToDataDetail = (row) => {
  try {
    // 获取videoDataList并进行安全检查
    const dataList = row.videoDataList || [];
    
    // 判断数据数量
    if (dataList.length === 1) {
      // 只有一条数据，直接跳转
      const dataId = dataList[0].dataId;
      router.push({
        name: "DataDetail",
        params: {
          id: dataId
        }
      });
    } else if (dataList.length > 1) {
      // 多条数据，显示选择对话框
      selectedDataList.value = dataList;
      showDataSelectDialog.value = true;
    } else {
      // 没有数据，给出提示
      ElMessage.warning('该任务没有关联的数据');
    }
  } catch (error) {
    console.error('跳转数据详情失败:', error);
    ElMessage.error('跳转详情页失败');
  }
};

// 从选择对话框中选择数据进行跳转
const selectAndGoToDetail = (data) => {
  if (data && data.dataId) {
    router.push({
      name: "DataDetail",
      params: {
        id: data.dataId
      }
    });
    showDataSelectDialog.value = false;
  }
}

const searchTasks = async () => {
  currentPage.value = 1
  await loadTaskList()
}

const resetFilter = async () => {
  filterTaskName.value = ''
  filterStartTime.value = ''
  filterEndTime.value = ''
  filterStatus.value = ''
  currentPage.value = 1
  await loadTaskList()
  ElMessage.info('已重置筛选条件')
}

const exportTask = async (row) => {
  try {
    // 校验2：单个任务超5G（适配totalFileSize字段）
    const taskSizeMB = row.totalFileSize ? Number(row.totalFileSize) : 0;
    if (taskSizeMB > MAX_SIZE_MB) {
      await ElMessageBox.alert(
          `任务"${row.taskName}"文件大小为${taskSizeMB.toFixed(1)}MB，超过5GB（5120MB）限制`,
          '导出失败',
          { type: 'warning' }
      );
      return;
    }

    // 初始化导出进度状态
    isExporting.value = true; // 显示全局进度条遮罩
    exportProgress.value = 0;
    progressText.value = "正在生成压缩包...";
    downloadSuccess.value = false;

    // 1. 获取压缩包地址
    ElMessage.info('正在获取压缩包信息...');
    const response = await taskAPI.exportVideoDataTask({
      taskIds: row.taskId,
    });

    if (response.code !== 0) {
      throw new Error(`接口错误：${response.msg || '获取压缩包地址失败'}`);
    }
    const fileUrl = response.data;
    if (!fileUrl) throw new Error('接口未返回压缩包地址');

    // 拼接完整 URL - 关键修复
    const fullFileUrl = `${API_CONFIG.IMAGE_URL}${fileUrl}`;

    // 2. 请求保存路径
    const defaultFileName = fileUrl.split('/').pop() || `任务${row.taskId}_导出_${dayjs().format('YYYYMMDDHHmmss')}.zip`;
    const savePathResult = await window.electronAPI.requestSavePath(defaultFileName);

    if (savePathResult.canceled) {
      ElMessage.info('已取消下载');
      return;
    }
    if (savePathResult.error) throw new Error(savePathResult.error);

    // 3. 下载文件（复用批量导出的带进度方法，绑定进度回调）
    progressText.value = "正在下载压缩包...";
    const downloadResult = await window.electronAPI.downloadFileWithProgress(
        {
          fileUrl: fullFileUrl,
          savePath: savePathResult.filePath
        },
        // 进度更新回调
        (progress) => {
          exportProgress.value = Math.floor(progress.percent * 100);
          progressText.value = `正在下载：${exportProgress.value}%（${progress.transferred} / ${progress.total}）`;
        }
    ).catch(error => {
      throw new Error(`下载失败: ${error.message}`);
    });

    // 4. 导出成功处理
    if (downloadResult.success) {
      exportProgress.value = 100;
      progressText.value = "导出完成！";
      downloadSuccess.value = true;
      const successMsg = `下载完成！文件保存至：${savePathResult.filePath}`;
      downloadMsg.value = successMsg;
      ElMessage.success(successMsg);
    } else {
      throw new Error(downloadResult.message || '文件下载失败');
    }

  } catch (error) {
    // 失败时重置进度状态
    exportProgress.value = 0;
    progressText.value = "导出失败";
    downloadSuccess.value = false;
    const errorMsg = `导出失败：${error.message}`;
    downloadMsg.value = errorMsg;
    ElMessage.error(errorMsg);
    console.error('单个导出异常：', error);
  } finally {
    // 最终关闭进度条（保留1秒成功状态）
    setTimeout(() => {
      isExporting.value = false;
      exportProgress.value = 0;
    }, downloadSuccess.value ? 1000 : 0);
  }
};

// 导入相关函数
const openFile = () => {
  showFileDialog.value = true;
  selectedFile.value = '';
};

const selectedFile = ref(null); // 选中的导入文件
const importLoading = ref(false); // 导入加载状态

const clearSelection = () => {
  selectedFile.value = null;
  ElMessage.info('已清除选中文件');
};

const openFileDialog = async () => {
  try {
    // 选择文件（获取路径等元数据）
    const result = await window.electronAPI.openFileDialog({
      title: '选择导入文件',
      filters: [{ name: 'ZIP 压缩包', extensions: ['zip'] }],
      properties: ['openFile']
    });

    if (result.canceled) {
      ElMessage.info('已取消文件选择');
      return;
    }

    const filePath = result.filePaths[0];
    const fileName = filePath.split('\\').pop();

    // 读取文件二进制内容
    const readResult = await window.electronAPI.readFileAsArrayBuffer(filePath);
    if (!readResult.success) {
      throw new Error(`读取文件失败：${readResult.error}`);
    }

    // 创建标准File对象
    const file = new File([readResult.data], fileName, {
      type: 'application/zip'
    });

    // 包装File和路径信息
    selectedFile.value = {
      file: file,
      path: filePath,
      name: fileName,
      size: file.size
    };

    ElMessage.success(`已选择文件：${fileName}`);

  } catch (error) {
    ElMessage.error(`文件处理失败：${error.message}`);
    console.error('错误详情：', error);
  }
};

const uploadFile = async () => {
  if (!selectedFile.value) {
    ElMessage.warning('请先选择要导入的文件');
    return;
  }

  // 初始化导入进度状态
  isImporting.value = true;
  importProgress.value = 0;
  importProgressText.value = "准备导入...";
  importLoading.value = true;

  try {
    // 1. 模拟文件验证阶段
    await new Promise(resolve => setTimeout(resolve, 800));
    importProgress.value = 15;
    importProgressText.value = "文件验证中...";

    // 2. 创建表单数据
    const formData = new FormData();
    formData.append('file', selectedFile.value.file);

    // 3. 上传文件（带进度跟踪）
    // 使用XMLHttpRequest实现进度监听
    // 关键修复：使用完整的API路径
    const xhr = new XMLHttpRequest();
    xhr.open('POST', `${API_CONFIG.BASE_URL}/system/videoTask/importVideoDataTask`, true);

    // 监听进度事件
    xhr.upload.addEventListener('progress', (e) => {
      if (e.lengthComputable) {
        const percent = Math.floor((e.loaded / e.total) * 100);
        // 上传进度占总进度的60%（15%~75%）
        const progress = 15 + Math.floor(percent * 0.6);
        importProgress.value = progress;
        importProgressText.value = `文件上传中：${progress}%`;
      }
    });

    // 发送请求并等待完成
    await new Promise((resolve, reject) => {
      xhr.onload = () => {
        if (xhr.status >= 200 && xhr.status < 300) {
          try {
            const result = JSON.parse(xhr.responseText);
            if (result.code === 0) {
              resolve(result);
            } else {
              reject(new Error(result.msg || '导入失败'));
            }
          } catch (error) {
            reject(new Error('解析响应失败'));
          }
        } else {
          reject(new Error(`HTTP错误: ${xhr.status}`));
        }
      };

      xhr.onerror = () => reject(new Error('网络错误'));
      xhr.send(formData);
    });

    // 4. 模拟服务器处理阶段（75%~100%）
    importProgressText.value = "服务器处理中...";
    const totalSteps = 25; // 25个步骤完成剩余25%进度
    for (let i = 0; i < totalSteps; i++) {
      await new Promise(resolve => setTimeout(resolve, 60));
      importProgress.value = 75 + Math.round((i / totalSteps) * 25);
    }

    // 5. 导入完成
    importProgress.value = 100;
    importProgressText.value = "导入完成！";
    ElMessage.success("导入成功！任务数据已更新");

    // 关闭弹窗并刷新列表
    showFileDialog.value = false;
    selectedFile.value = null;
    await loadTaskList();

  } catch (error) {
    ElMessage.error(`导入失败：${error.message}`);
    importProgressText.value = "导入失败";
  } finally {
    // 延迟关闭进度条，展示完成状态
    setTimeout(() => {
      isImporting.value = false;
      importProgress.value = 0;
      importLoading.value = false;
    }, 1000);
  }
};

// 任务编辑相关函数
const addNewTask = async () => {
  isEdit.value = false
  resetForm()
  showAddDialog.value = true
  // 加载采集数据选项
  await loadCollectionDataOptions()
}

const editTask = async (row) => {
  isEdit.value = true
  taskForm.value = {
    taskId: row.taskId,
    taskName: row.taskName,
    startTime: row.startTime,
    endTime: row.endTime,
    status: row.status,
    remark: row.remark || '',
    dataIds: row.dataIds ? row.dataIds.split(',').map(id => parseInt(id)) : [],
    taskType: row.taskType ? parseInt(row.taskType) : null
  }

  // 保存videoDataList用于显示关联数据
  currentTaskVideoDataList.value = row.videoDataList || [];

  showAddDialog.value = true

  // 编辑时也需要加载采集数据选项
  await loadCollectionDataOptions()
}

const saveTask = async () => {
  try {
    // 检查表单引用是否存在
    if (!taskFormRef.value) {
      ElMessage.error('表单引用不存在，请重试');
      return;
    }

    // 确保dataIds字段存在
    if (!taskForm.value.dataIds) {
      taskForm.value.dataIds = [];
    }

    // 清除之前的验证状态
    taskFormRef.value.clearValidate();

    // 验证必填字段
    const validationPromises = [
      taskFormRef.value.validateField('taskName'),
      taskFormRef.value.validateField('startTime'),
      taskFormRef.value.validateField('endTime'),
      taskFormRef.value.validateField('status'),
      taskFormRef.value.validateField('remark'),
      taskFormRef.value.validateField('taskType')
    ];

    // dataIds字段已改为非必填，不需要额外验证

    try {
      await Promise.all(validationPromises);
    } catch (error) {
      console.log('表单验证失败:', error);
      return;
    }

    saveLoading.value = true

    // 处理时间格式，确保包含毫秒
    const formatTimeWithMilliseconds = (timeStr) => {
      if (!timeStr) return '';
      // 如果时间格式不包含毫秒，添加毫秒
      if (timeStr.split(':').length === 3) {
        return timeStr + ':000';
      }
      return timeStr;
    };

    // 构建任务数据
    const taskData = {
      taskName: taskForm.value.taskName || '',
      startTime: formatTimeWithMilliseconds(taskForm.value.startTime),
      endTime: formatTimeWithMilliseconds(taskForm.value.endTime),
      status: taskForm.value.status || '',
      remark: taskForm.value.remark || '',
      taskType: taskForm.value.taskType ? parseInt(taskForm.value.taskType) : null
    }

    // 添加dataIds字段
    if (taskForm.value.dataIds && taskForm.value.dataIds.length > 0) {
      taskData.dataIds = taskForm.value.dataIds.join(',');
    }

    let result;
    if (isEdit.value) {
      // 更新任务 - 关键修复：确保API路径正确
      result = await taskAPI.updateTask(taskForm.value.taskId, taskData);
    } else {
      // 添加新任务 - 关键修复：确保API路径正确
      result = await taskAPI.addTask(taskData);
    }

    if (result && result.code === 0) {
      ElMessage.success(isEdit.value ? '任务更新成功' : '任务添加成功');
      showAddDialog.value = false;
      // 延迟重置表单
      nextTick(() => {
        resetForm();
      });
      // 刷新任务列表
      await loadTaskList();
    } else {
      throw new Error(result?.msg || (isEdit.value ? '更新任务失败' : '添加任务失败'));
    }
  } catch (error) {
    console.error('保存任务失败:', error);
    ElMessage.error(`保存任务失败: ${error.message}`);
  } finally {
    saveLoading.value = false;
  }
}

const cancelEdit = () => {
  showAddDialog.value = false
  // 延迟重置表单
  nextTick(() => {
    resetForm()
  })
}

const resetForm = () => {
  taskForm.value = {
    taskId: '',
    taskName: '',
    startTime: '',
    endTime: '',
    status: '0',
    remark: '',
    dataIds: [],
    taskType: null
  }
  // 清空videoDataList
  currentTaskVideoDataList.value = []
  // 安全地重置表单字段
  nextTick(() => {
    if (taskFormRef.value && typeof taskFormRef.value.resetFields === 'function') {
      taskFormRef.value.resetFields()
    }
  })
}

const deleteTask = async (row) => {
  try {
    await ElMessageBox.confirm(
        `确定要删除任务"${row.taskName}"吗？\n\n此操作不可恢复！`,
        '确认删除',
        {
          confirmButtonText: '确定删除',
          cancelButtonText: '取消',
          type: 'warning'
        }
    )

    // 关键修复：确保删除接口路径正确
    const result = await taskAPI.deleteTask(row.taskId);
    console.log('删除任务API响应:', result);
    if (result && result.code === 0) {
      ElMessage.success('删除成功');
      // 刷新任务列表
      await loadTaskList();
    } else {
      throw new Error(result?.msg || '删除任务失败');
    }
  } catch (error) {
    if (error === 'cancel') {
      ElMessage.info('已取消删除');
    } else {
      console.error('删除任务失败:', error);
      ElMessage.error(`删除任务失败: ${error.message}`);
    }
  }
}

const viewCollectionDetail = (row) => {
  ElMessage.info(`查看采集详情: ${row.id}`)
}

// 分页处理
const handleSizeChange = async (val) => {
  pageSize.value = val
  currentPage.value = 1
  await loadTaskList()
}

const handleCurrentChange = async (val) => {
  currentPage.value = val
  await loadTaskList()
}

// 页面初始化
onMounted(async () => {
  // 页面加载时加载一次任务类型选项
  await loadTaskTypeOptions();

  // 检查是否从详情页返回
  const isFromDetail = sessionStorage.getItem('fromTaskDetail') === 'true';
  const isFromMenu = sessionStorage.getItem('isFromMenu') === 'true';

  // 清除标记
  sessionStorage.removeItem('fromTaskDetail');
  sessionStorage.removeItem('isFromMenu');

  if (isFromDetail) {
    // 从详情页返回，尝试恢复缓存的数据和状态
    const cachedDataStr = sessionStorage.getItem('taskCachedData');
    const cachedFiltersStr = sessionStorage.getItem('taskCachedFilters');

    if (cachedDataStr && cachedFiltersStr) {
      console.log('从任务详情页返回，恢复缓存数据');
      const cachedData = JSON.parse(cachedDataStr);
      const cachedFilters = JSON.parse(cachedFiltersStr);

      taskList.value = cachedData.data;
      total.value = cachedData.total;
      currentPage.value = cachedData.currentPage;
      pageSize.value = cachedData.pageSize;
      filterTaskName.value = cachedFilters.filterTaskName || '';
      filterStartTime.value = cachedFilters.filterStartTime || '';
      filterEndTime.value = cachedFilters.filterEndTime || '';
      filterStatus.value = cachedFilters.filterStatus || '';

      // 清除缓存
      sessionStorage.removeItem('taskCachedData');
      sessionStorage.removeItem('taskCachedFilters');
    } else {
      console.log('没有找到缓存数据，重新加载');
      await loadTaskList();
    }
  } else {
    // 首次加载或从菜单进入，重新加载数据
    console.log('首次加载或从菜单进入，重新加载数据');
    await loadTaskList();
  }

  console.log('任务管理模块初始化完成');
});
</script>

<style scoped>

/* 数据选择对话框样式 */
.data-cards-container {
  max-height: 500px;
  overflow-y: auto;
  padding: 10px 0;
}

.data-card {
  margin-bottom: 16px;
  transition: transform 0.2s, box-shadow 0.2s;
}

.data-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.card-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.data-info {
  flex: 1;
}

.data-info-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.info-item {
  display: flex;margin-right: 40px;
  align-items: center;
  white-space: nowrap;
}

.info-item:last-child {
  /* 移除最后一个元素的margin-bottom，因为现在是水平排列 */
}

.info-label {
  font-weight: 500;
  color: #909399;
  margin-right: 8px;
  min-width: 50px;
}

.info-value {
  color: #303133;
  font-size: 14px;
  font-weight: 500;
}

.action-buttons {
  margin-left: 20px;
}

/* 样式内容保持不变 */
.task-management {
  padding: 0 10px;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.filter-bar {
  background: white;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  flex-shrink: 0;
}

.filter-controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.filter-controls .el-input,
.filter-controls .el-date-picker,
.filter-controls .el-select,
.filter-controls .el-button {
  flex-shrink: 0;
}

.table-section {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.table-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  border-bottom: 1px solid #f0f0f0;
  flex-shrink: 0;
}

.table-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #333;
}

.table-controls {
  display: flex;
  gap: 10px;
}

/* 批量导出按钮样式优化 */
.table-controls .el-button:first-child {
  background-color: #2d8cf0; /* 稍深的蓝色，区分单个导出 */
}
.table-controls .el-button:first-child:hover {
  background-color: #1e78d6;
}
/* 禁用状态样式 */
.table-controls .el-button:first-child:disabled {
  background-color: #a0cfff;
  border-color: #a0cfff;
  cursor: not-allowed;
}

/* 已选任务大小提示样式 */
.selected-size-hint {
  margin-right: 20px;
  color: #666;
  font-size: 13px;
  white-space: nowrap;
}

.table-container {
  flex: 1;
  overflow: hidden;
  padding: 0 20px;
}

.pagination-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  border-top: 1px solid #f0f0f0;
  flex-shrink: 0;
}

.pagination-info {
  color: #666;
  font-size: 14px;
}

.time-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}

.action-buttons {
  display: flex;
  gap: 5px;
  justify-content: center;
}

.task-data-content {
  margin-top: 10px;
}

.stats-content {
  display: flex;
  gap: 40px;
  padding: 20px;
}

.stat-item {
  text-align: center;
}

.stat-item h4 {
  margin: 0 0 10px 0;
  color: #666;
  font-size: 14px;
}

.stat-number {
  margin: 0;
  font-size: 24px;
  font-weight: bold;
  color: #409eff;
}

/* 关联数据显示样式 */
.associated-data-container {
  width: 100%;
  min-height: 120px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  padding: 16px;
  background: #fafbfc;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.data-summary {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 12px;
  font-size: 13px;
  color: #606266;
  font-weight: 500;
}

.data-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
}

.data-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  transition: all 0.2s ease;
}

.data-item:hover {
  background: #f8f9fa;
  border-color: #c0c4cc;
}

.item-icon {
  color: #409eff;
  font-size: 14px;
}

.item-text {
  font-size: 13px;
  color: #606266;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}

.no-associated-data {
  text-align: center;
  padding: 0;
  color: #909399;
  width: 100%;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 导出Loading遮罩样式 */
.export-loading-mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.6);
  z-index: 9999; /* 确保层级高于所有组件 */
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: white;
  padding: 40px 30px;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
}

.loading-spinner {
  font-size: 40px;
  color: #409eff;
  margin-bottom: 15px;
}

.progress-text {
  font-size: 16px;
  color: #333;
  margin-bottom: 10px;
  text-align: center;
  width: 100%;
}
.el-icon{
  display: none !important;
}

/* 数据选择对话框样式 */
.data-cards-container {
  max-height: 400px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.data-card {
  width: 100%;
}

.card-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.data-info {
  flex: 1;
}

.action-buttons {
  margin-left: 20px;
}
</style>
